package com.yan.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.enums.ApiErrorCode;
import com.baomidou.mybatisplus.extension.exceptions.ApiException;
import com.esotericsoftware.minlog.Log;
import com.yan.domain.SysMenu;
import com.yan.feign.JwtToken;
import com.yan.feign.Oauth2FeignClient;
import com.yan.model.loginResult;
import com.yan.service.SysLoginService;
import com.yan.service.SysMenuService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.jwt.Jwt;
import org.springframework.security.jwt.JwtHelper;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

@Service
@Slf4j
public class SysLoginServiceImpl implements SysLoginService {

    @Autowired
    private Oauth2FeignClient oauth2FeignClient;

    @Autowired
    private SysMenuService sysMenuService;

    @Autowired
    private RedisTemplate redisTemplate;


    @Value("${basic.token:Basic Y29pbi1hcGk6Y29pbi1zZWNyZXQ=}")
    private String basicToken;

    @Override
    public loginResult login(String username, String password) {
        log.info("用户{}开始登陆",username);
        ResponseEntity<JwtToken> tokenResponseEntity = oauth2FeignClient.getToken("password",username,password,"admin_type",basicToken);
        if (tokenResponseEntity.getStatusCode()!= HttpStatus.OK){
            throw new ApiException(ApiErrorCode.FAILED);
        }
        JwtToken jwtToken = tokenResponseEntity.getBody();
        Log.info("远程调用授权服务器成功,获取的token为{}", JSON.toJSONString(jwtToken,true));
        String token = jwtToken.getAccessToken();

        Jwt jwt = JwtHelper.decode(token);
        String jwtJsonStr = jwt.getClaims();
        JSONObject jsonObject = JSON.parseObject(jwtJsonStr);
        Long userId = Long.valueOf(jsonObject.getString("user_name"));
        List<SysMenu> menus = sysMenuService.getMenusByUserId(userId);

        JSONArray authorities = jsonObject.getJSONArray("authorities");
        List<SimpleGrantedAuthority> authorityList = authorities.stream().map(
                item -> new SimpleGrantedAuthority(item.toString())
        ).collect(Collectors.toList());
        redisTemplate.opsForValue().set(token,"",jwtToken.getExpiresIn(), TimeUnit.SECONDS);
        return new loginResult(jwtToken.getTokenType()+" "+token, menus, authorityList);

    }
}
